home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 014 / gfxmem / gfxmem.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  11KB  |  376 lines

  1. /*
  2.  *  gfxmem.c  - graphically display available memory.  Quick program
  3.  *     that's a freebie.  Give it to anyone you please, just don't sell it.
  4.  *
  5.  *       Version 0.0 - initial version, released on INFO-AMIGA.
  6.  *       Version 0.1 - added numeric indication of available and used memory
  7.  *                     in bar graphs.
  8.  *       Version 0.2 - added condition compilation for timer.device code.  If
  9.  *                     I can figure out how to make it create timer signals,
  10.  *                     then I can define USE_TIMER for much more prompt
  11.  *                     response to window sizing attempts.  Oh well.
  12.  *       Version 0.3 - removed conditional compilation for timer.device
  13.  *                     code.  We now use the timer, and all seems well.
  14.  *       Version 0.4 - calculate character data placement according to
  15.  *                     display preferences.  Check for updated preferences
  16.  *                     while running.
  17.  *     Version 0.5 - don't display fast memory if none exists.  Handle
  18.  *               Lattice C 3.03 in V1.1 update kit that insists on
  19.  *               creating a window for stdin, stdout and stderr with-
  20.  *               out asking.  Foo!
  21.  *
  22.  *  TODO:
  23.  *       Add menu selection package to display Kbytes or percent of memory
  24.  *       used and free.
  25.  *
  26.  *       Add requestor to display statistics like min and max for free and
  27.  *       avail, time running, etc..
  28.  *
  29.  *
  30.  *                 Copyright (C) 1985,
  31.  *                 Louis A. Mamakos
  32.  *                 Software & Stuff
  33.  */
  34. static char copyright[] = 
  35.  "Copyright (C) 1985, 1986\r\nLouis A. Mamakos\r\nSoftware & Stuff";
  36.  
  37. #define  PROG_VER "GfxMem 0.5 "
  38.  
  39. #include <exec/types.h>
  40. #include <exec/nodes.h>
  41. #include <exec/lists.h>
  42. #include <exec/exec.h>
  43. #include <exec/execbase.h>
  44. #include <exec/ports.h>
  45. #include <exec/devices.h>
  46. #include <exec/memory.h>
  47. #include <devices/timer.h>
  48. #include <hardware/blit.h>
  49. #include <graphics/copper.h>
  50. #include <graphics/regions.h>
  51. #include <graphics/rastport.h>
  52. #include <graphics/gfxbase.h>
  53. #include <graphics/gfxmacros.h>
  54. #include <graphics/gels.h>
  55. #include <intuition/intuition.h>
  56. #include <stdio.h>
  57.  
  58. extern struct ExecBase *SysBase;
  59. struct IntuitionBase *IntuitionBase;
  60. struct GfxBase *GfxBase;
  61. struct MsgPort *timerport, *CreatePort();
  62. struct timerequest timereq;
  63.  
  64. struct NewWindow NewWindow = {
  65.    10, 10, 450, 50,           /* sizes */
  66.    -1, -1,                    /* pens */
  67.    CLOSEWINDOW | ACTIVEWINDOW | SIZEVERIFY |
  68.                  NEWSIZE | NEWPREFS | REFRESHWINDOW,   /* IDCMP flags */
  69.    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH,
  70.    NULL, NULL,                /* gadget, checkmark */
  71.    PROG_VER,                  /* title */
  72.    NULL, NULL,                /* screen, bitmap */
  73.    100, 30, 640, 100,         /* min and max sizing */
  74.    WBENCHSCREEN               /* on the workbench screen */
  75. };
  76.  
  77. ULONG    AvailMem ();
  78. ULONG    ChipMax, FastMax, ChipFree, FastFree;
  79. ULONG    ChipLargest, FastLargest;
  80. int      dont_draw, char_size;
  81.  
  82. /*
  83.  *  maxsize -- determine the total maximum size for all regions
  84.  *   of the given type.  This code must be executed while
  85.  *   FORBIDDEN (it accesses shared system structures).
  86.  */
  87. ULONG
  88. maxsize (t)
  89.     unsigned long t;
  90. {
  91.     /* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */
  92.     ULONG size = 0;
  93.     struct MemHeader *mem;
  94.     struct ExecBase *eb = SysBase;
  95.  
  96.     for (mem = (struct MemHeader *) eb->MemList.lh_Head;
  97.                         mem->mh_Node.ln_Succ; mem = mem->mh_Node.ln_Succ)
  98.        if (mem -> mh_Attributes & t)
  99.           size += ((ULONG) mem->mh_Upper - (ULONG) mem->mh_Lower);
  100.     return size;
  101. }
  102.  
  103. getsizes()
  104. {
  105.    if (ChipMax == 0) {  /* only do this once */
  106.       Forbid ();
  107.       ChipMax = maxsize (MEMF_CHIP);
  108.       FastMax = maxsize (MEMF_FAST);
  109.       Permit();
  110.    }
  111.    ChipFree = AvailMem (MEMF_CHIP);
  112.    ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST);
  113.    FastFree = AvailMem (MEMF_FAST);
  114.    FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST);
  115. }
  116.  
  117. starttimer()
  118. {
  119.    timereq.tr_time.tv_secs = 1;
  120.    timereq.tr_time.tv_micro = 0;
  121.    timereq.tr_node.io_Command = TR_ADDREQUEST;
  122.    timereq.tr_node.io_Flags = 0;
  123.    timereq.tr_node.io_Error = 0;
  124.    timereq.tr_node.io_Message.mn_ReplyPort = timerport;
  125.    SendIO((char *) &timereq.tr_node);
  126. }
  127.  
  128. /*
  129.  *  This function is called during startup and when new preferences are
  130.  *  selected.  Get the font size from the Preferences structure.
  131.  */
  132. newprefs()
  133. {
  134.    char FontHeight;
  135.  
  136.    GetPrefs(&FontHeight, sizeof (FontHeight));
  137.    switch (FontHeight) {
  138.    case TOPAZ_SIXTY:
  139.       char_size = 11;
  140.       break;
  141.  
  142.    case TOPAZ_EIGHTY:
  143.       char_size = 8;
  144.       break;
  145.  
  146.    default:
  147.       char_size = 12;
  148.    }
  149. }
  150.  
  151.  
  152. /*
  153.  *  Main function.  Call intution to create a new window for us on the
  154.  *  screen.  Go from there.
  155.  *
  156.  * We no longer have our main() function called main();  instead we
  157.  * use _main().  This keeps the standard _main.c function from Lattice
  158.  * from creating a window for us that's not going to get used, and will
  159.  * just clutter things. They figure that they are going to help us out, and
  160.  * create a CON: type window for us.  This is ugly, and of no use to
  161.  * us.  Gak!  Why don't they worry about their stupid compiler 
  162.  * generating good (or even correct!) code with out this feeping
  163.  * creaturism.  Flame off. 
  164.  */
  165. _main(args)
  166.    char *args;
  167. {
  168.    struct Window *w;
  169.    struct IntuiMessage *msg, *GetMsg();
  170.    int waitmask;
  171.  
  172.    timerport = NULL;
  173.    IntuitionBase = (struct IntuitionBase *)
  174.                    OpenLibrary("intuition.library", 0);
  175.    if (IntuitionBase == NULL)
  176.       _exit(1);
  177.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  178.    if (GfxBase == NULL) {
  179.       CloseLibrary(IntuitionBase);
  180.       _exit(2);
  181.    }
  182.  
  183.    getsizes();
  184.    if (FastMax == 0)            /* if no fast memory in system */
  185.     NewWindow.Height = 30;        /* make window smaller */
  186.  
  187.    if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) {
  188.       CloseLibrary(GfxBase);
  189.       CloseLibrary(IntuitionBase);
  190.       _exit(3);
  191.    }
  192.    if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
  193.       CloseWindow(w);
  194.       CloseLibrary(GfxBase);
  195.       CloseLibrary(IntuitionBase);
  196.       _exit(5);
  197.    }
  198.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
  199.       DeletePort(timerport);
  200.       CloseWindow(w);
  201.       CloseLibrary(GfxBase);
  202.       CloseLibrary(IntuitionBase);
  203.       _exit(4);
  204.    }
  205.  
  206.    newprefs();
  207.    redraw(w, TRUE);
  208.    starttimer();
  209.    waitmask = (1 << w->UserPort->mp_SigBit) |
  210.               (1 << timerport->mp_SigBit);
  211.    for(;;) {
  212.       Wait(waitmask);
  213.       while (msg = GetMsg(w->UserPort)) {
  214.          switch (msg->Class) {
  215.          case CLOSEWINDOW:
  216.             ReplyMsg(msg);
  217.             AbortIO(&timereq);
  218.             CloseDevice(&timereq);
  219.             DeletePort(timerport);
  220.             CloseWindow(w);
  221.             CloseLibrary(GfxBase);
  222.             CloseLibrary(IntuitionBase);
  223.             _exit(0);
  224.  
  225.          case REFRESHWINDOW:
  226.             BeginRefresh(w);
  227.             dont_draw = 0;
  228.             redraw(w, TRUE);
  229.             EndRefresh(w, TRUE);
  230.  
  231.          case ACTIVEWINDOW:
  232.             /* when window is active, display version */
  233.             SetWindowTitles(w, -1, 
  234.                 "Graphical memory display by Louis A. Mamakos");
  235.             break;
  236.  
  237.          case NEWSIZE:
  238.             dont_draw = 0;
  239.             redraw(w, TRUE);
  240.             break;
  241.  
  242.          case SIZEVERIFY:
  243.             dont_draw = 1;
  244.             break;
  245.  
  246.          case NEWPREFS:
  247.             newprefs();
  248.             redraw(w, TRUE);
  249.             break;
  250.          }
  251.          ReplyMsg(msg);
  252.       } /* while */
  253.  
  254.       if (GetMsg(timerport)) {
  255.          redraw(w, FALSE);
  256.          starttimer();
  257.       }
  258.    } /* for */
  259. }
  260.  
  261.  
  262. #define TOP w->BorderTop
  263. #define BOTTOM w->Height - w->BorderBottom
  264. #define LEFT w->BorderLeft
  265. #define RIGHT w->Width - w->BorderRight
  266. #define GUTTER 3        /* pixels of veritical spacing between bars */
  267.  
  268. /*
  269.  *  Redraw all of the stuff in the window.
  270.  */
  271. redraw(w, refresh)
  272.    struct Window *w;
  273.    int refresh;
  274. {
  275.    register struct RastPort *rp = w->RPort;
  276.    register short x_min, y_min, x_max, y_max;
  277.    static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale;
  278.    static long old_chipfree, old_fastfree;
  279.    char txt[10];
  280.  
  281.    if (dont_draw)
  282.       return 0;
  283.    getsizes();
  284.    if (refresh) {
  285.       SetAPen(rp, 2);
  286.       SetBPen(rp, 2);
  287.       SetOPen(rp, 2);
  288.       RectFill(rp, LEFT, TOP, RIGHT, BOTTOM);
  289.       /*  recalculate the spacing paramters for this sized window */
  290.       AvailWidth = w->Width - w->BorderRight - w->BorderLeft;
  291.       AvailHeight = w->Height - w->BorderTop - w->BorderBottom;
  292.       HorizSpace = AvailWidth/20; /* use 5% of available space as margin */
  293.       AvailWidth -= HorizSpace * 2;
  294.       if (FastMax)
  295.     Thickness = (AvailHeight - GUTTER*3) / 2;
  296.       else
  297.     Thickness = (AvailHeight - GUTTER*2);
  298.  
  299.       if (ChipMax > FastMax)
  300.          Scale = ChipMax/AvailWidth;
  301.       else
  302.          Scale = FastMax/AvailWidth;
  303.    } else
  304.       if (old_chipfree == ChipFree && old_fastfree == FastFree)
  305.          return 0;
  306.    old_chipfree = ChipFree;
  307.    old_fastfree = FastFree;
  308.    SetAPen(rp, 3);
  309.    SetOPen(rp, 1);
  310.    SetBPen(rp, 2);
  311.    x_min = HorizSpace;
  312.    y_min = TOP + GUTTER;
  313.    x_max = x_min + (ChipMax - ChipFree)/Scale;
  314.    y_max = y_min + Thickness;
  315.    RectFill(rp, x_min, y_min, x_max, y_max);
  316.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  317.       sprintf(txt, "%4dK", (ChipMax - ChipFree) >> 10);
  318.       SetAPen(rp, 1);
  319.       SetBPen(rp, 3);
  320.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  321.       Text(rp, txt, 5);
  322.    }
  323.    x_min = x_max;
  324.    x_max = x_min + ChipFree/Scale;
  325.    SetAPen(rp, 0);
  326.    RectFill(rp, x_min, y_min, x_max, y_max);
  327.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  328.       sprintf(txt, "%4dK", ChipFree>>10);
  329.       SetAPen(rp, 1);
  330.       SetBPen(rp, 0);
  331.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  332.       Text(rp, txt, 5);
  333.    }
  334.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  335.       SetAPen(rp, 1);
  336.       SetBPen(rp, 2);
  337.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 4);
  338.       Text(rp, "C", 1);
  339.    }
  340.  
  341.    if (FastMax == 0)
  342.     return;
  343.  
  344.    x_min = HorizSpace;
  345.    x_max = x_min + (FastMax - FastFree)/Scale;
  346.    y_min = y_max + GUTTER;
  347.    y_max = y_min + Thickness;
  348.    SetAPen(rp, 3);
  349.    RectFill(rp, x_min, y_min, x_max, y_max);
  350.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  351.       sprintf(txt, "%4dK", (FastMax - FastFree) >> 10);
  352.       SetAPen(rp, 1);
  353.       SetBPen(rp, 3);
  354.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  355.       Text(rp, txt, 5);
  356.    }
  357.    x_min = x_max;
  358.    x_max = x_min + FastFree/Scale;
  359.    SetAPen(rp, 0);
  360.    RectFill(rp, x_min, y_min, x_max, y_max);
  361.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  362.       sprintf(txt, "%4dK", FastFree>>10);
  363.       SetAPen(rp, 1);
  364.       SetBPen(rp, 0);
  365.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  366.       Text(rp, txt, 5);
  367.    }
  368.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  369.       SetAPen(rp, 1);
  370.       SetBPen(rp, 2);
  371.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 3);
  372.       Text(rp, "F", 1);
  373.    }
  374. }
  375.  
  376.